﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Rison.BusinessFacade.Common
{
    internal sealed class ConditionConverter
    {
        private ConditionConverter()
        {
        }

        private static string GetConnectSign(NextConnectSign sign)
        {
            switch (sign)
            {
                case NextConnectSign.And:
                    return " and ";
                case NextConnectSign.OR:
                    return " or ";
                case NextConnectSign.And_LeftParen:
                    return " and (";
                case NextConnectSign.RightParen:
                    return ")";
                case NextConnectSign.RightParen_And:
                    return ") and ";
                default:
                    return string.Empty;
            }
        }

        private static string GetValue(Condition c)
        {
            if (c.NeedQuotes)
                return "'" + c.Value + "'";

            return c.Value;
        }

        public static string ConvertToSqlConditionString(List<Condition> conditions)
        {
            StringBuilder builder = new StringBuilder();
            
            for (int i = 0; i < conditions.Count; i++)
            {
                builder.Append(conditions[i].FieldName);

                switch (conditions[i].Operator)
                {
                    case SqlOperator.Equal:
                        builder.AppendFormat("={0}", GetValue(conditions[i])); break;
                    case SqlOperator.NotEqual :
                        builder.AppendFormat("<>{0}", GetValue(conditions[i])); break;
                    case SqlOperator.LargerThan:
                        builder.AppendFormat(">{0}", GetValue(conditions[i])); break;
                    case SqlOperator.LessThan:
                        builder.AppendFormat("<{0}", GetValue(conditions[i])); break;
                    case SqlOperator.LargerEqual :
                        builder.AppendFormat(">={0}", GetValue(conditions[i])); break;
                    case SqlOperator.LessEqual :
                        builder.AppendFormat("<={0}", GetValue(conditions[i])); break;
                    case SqlOperator.Like :
                        builder.AppendFormat(" like '%{0}%'", conditions[i].Value); break;
                    case SqlOperator.In :
                        builder.AppendFormat(" in ({0})", GetValue(conditions[i])); break;
                    case SqlOperator.NotIn :
                        builder.AppendFormat(" not in ({0})", GetValue(conditions[i])); break;
                    case SqlOperator.Null :
                        builder.Append(" is null"); break;
                    case SqlOperator.NotNull :
                        builder.Append(" is not null"); break;
                    case SqlOperator.Exists :
                        builder.AppendFormat(" exists ({0})", GetValue(conditions[i])); break;
                    case SqlOperator.NotExists :
                        builder.AppendFormat(" not exists ({0})", GetValue(conditions[i])); break;
                }

                if (i < conditions.Count - 1)
                    builder.Append(GetConnectSign(conditions[i].ConnectSign));
                else if (conditions[i].ConnectSign == NextConnectSign.RightParen || conditions[i].ConnectSign == NextConnectSign.RightParen_And)
                    builder.Append(")");
            }

            return builder.ToString();
        }

    }
}
